#include <Astronomy/RiseTransitSet.hpp>
#include "Astronomy/SolarTerms.hpp"
#include "gtest/gtest.h"

int main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);

    return RUN_ALL_TESTS();
}


TEST(RiseTransitSet, St)
{
    RiseTransitSet ristTransitSet(2.0312723552949694, 0.6963863715457375);
    auto           sun = ristTransitSet.St(2921.676712963889);

    ASSERT_EQ(sun.H, 3.140553495505472);
    ASSERT_EQ(sun.Rise, 2921.4832909571523);
    ASSERT_EQ(sun.Set, 2921.8746065155624);
    ASSERT_EQ(sun.Transit, 2921.6789051576334);
    ASSERT_EQ(sun.LowerTransit, 2922.179069821147);
    ASSERT_EQ(sun.GetDescription(), "");

    auto horizonEntry = sun.GetEntry(Twilight::Type::Horizon);
    ASSERT_EQ(horizonEntry.HourAngle, 1.229222515000199);
    ASSERT_EQ(horizonEntry.Dawn, 2921.4832909571523);
    ASSERT_EQ(horizonEntry.Dusk, 2921.8746065155624);

    auto civilEntry = sun.GetEntry(Twilight::Type::Civil);
    ASSERT_EQ(civilEntry.HourAngle, 1.3617950154222846);
    ASSERT_EQ(civilEntry.Dawn, 2921.462185096924);
    ASSERT_EQ(civilEntry.Dusk, 2921.895713036198);

    auto nauticalEntry = sun.GetEntry(Twilight::Type::Nautical);
    ASSERT_EQ(nauticalEntry.HourAngle, 1.5097408584335825);
    ASSERT_EQ(nauticalEntry.Dawn, 2921.438632158807);
    ASSERT_EQ(nauticalEntry.Dusk, 2921.919267104534);

    auto AstronomEntry = sun.GetEntry(Twilight::Type::Astronomical);
    ASSERT_EQ(AstronomEntry.HourAngle, 1.65310591850018);
    ASSERT_EQ(AstronomEntry.Dawn, 2921.4158090481137);
    ASSERT_EQ(AstronomEntry.Dusk, 2921.9420918765118);


}
TEST(RiseTransitSet, Mt)
{
    RiseTransitSet ristTransitSet(2.0312723552949694, 0.6963863715457375);
    auto           moon = ristTransitSet.Mt(2921.676712963889);

    ASSERT_EQ(moon.H, -3.121373539483507);
    ASSERT_EQ(moon.Rise, 2921.2018019933303);
    ASSERT_EQ(moon.Set, 2921.666756571323);
    ASSERT_EQ(moon.Transit, 2921.437366540255);
    ASSERT_EQ(moon.LowerTransit, 2921.951606455802);

    ASSERT_EQ(moon.GetDescription(), "");

    auto horizonEntry = moon.GetEntry(Twilight::Type::Horizon);
    ASSERT_EQ(horizonEntry.HourAngle, 1.4016609840968228);
    //ASSERT_EQ(horizonEntry.Dawn, 2921.2033703601924);
    //ASSERT_EQ(horizonEntry.Dusk, 2921.6713083318564);

}


TEST(SolarTerms, CalcQiAccurate)
{
    ASSERT_EQ(SolarTerms::CalcQiAccurate(8011), 465394.43007728184);
    ASSERT_EQ(SolarTerms::CalcQiAccurateOnJulianDate(8011), 8010.7479660400413);
}
TEST(SolarTerms, CalcSuoAccurate)
{
    ASSERT_EQ(SolarTerms::CalcSuoAccurate(8038), 37783.930979070385);
    ASSERT_EQ(SolarTerms::CalcSuoAccurateOnJulianDate(8038), 8037.6065881347067);  
}

#include <SexagenaryCycle.hpp>

bool VerifySexagenaryCycle(unsigned int ordinal, HeavenlyStem hs, EarthlyBranch eb)
{
    auto [ehs,eeb] = SexagenaryCycle::FromOrdinal(ordinal);
    if(hs != ehs)
        return false;
    if(eb != eeb)
        return false;
    return true;
}

TEST(SexagenaryCycle, VerifyFromOrdinal)
{

    ASSERT_EQ(VerifySexagenaryCycle(39,HeavenlyStem::Gui,EarthlyBranch::Mao), true);
    ASSERT_EQ(VerifySexagenaryCycle(9,HeavenlyStem::Gui,EarthlyBranch::You), true);
    ASSERT_EQ(VerifySexagenaryCycle(39,HeavenlyStem::Geng,EarthlyBranch::Wei), false);
}

TEST(SexagenaryCycle, VerifyToOrdinal)
{ 
    ASSERT_EQ(SexagenaryCycle::ToOrdinal(HeavenlyStem::Bing, EarthlyBranch::Shen), 32);
    ASSERT_EQ(SexagenaryCycle::ToOrdinal(HeavenlyStem::Wu, EarthlyBranch::Zi), 24);
    ASSERT_EQ(SexagenaryCycle::ToOrdinal(HeavenlyStem::Ding, EarthlyBranch::Chou), 13);
    ASSERT_EQ(SexagenaryCycle::ToOrdinal(HeavenlyStem::Wu, EarthlyBranch::Shen), 44);
    ASSERT_EQ(SexagenaryCycle::ToOrdinal(HeavenlyStem::Ding, EarthlyBranch::Shen), -1);
    ASSERT_EQ(SexagenaryCycle::ToOrdinal(HeavenlyStem::Jia, EarthlyBranch::Chou), -1);
}
TEST(SexagenaryCycleDate, Verify)
{
    SexagenaryCycleDate scDate(8925.668182870373,2.0312723552949694);

    ASSERT_EQ(scDate.scYear, 40);
    ASSERT_EQ(scDate.scMonth, 6);
    ASSERT_EQ(scDate.scDay, 40);
    ASSERT_EQ(scDate.scHour, 6);
}
#include "Astronomy/CDynamicalTime.hpp"

TEST(CDynamicalTime, TDUT)
{ 
    ASSERT_EQ(CDynamicalTime::TDUT(8925.668182870373), 0.00082543465052750719);
}